{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def find_index_of_smallest_value(A: List[int]):\n",
    "    minimum = 101\n",
    "    i = 0\n",
    "    for index, val in enumerate(A):\n",
    "        if val < minimum:\n",
    "            minimum = val\n",
    "            i = index\n",
    "    return i"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "find_index_of_smallest_value([1,2,3])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "find_index_of_smallest_value([1,2,-3])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "A = [\n",
    "    [1,2,3],\n",
    "    [4,5,6],\n",
    "    [7,8,9]\n",
    "]\n",
    "length = len(A)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "def func(row_index, previous_selection, sum_):\n",
    "    if (row_index >= length):\n",
    "        return [sum_]\n",
    "    \n",
    "    row = A[row_index]\n",
    "    results = []\n",
    "    \n",
    "    index = previous_selection-1\n",
    "    if 0 <= index < length:\n",
    "        selection = row[index]\n",
    "        results += func(row_index+1, index, sum_+selection)\n",
    "    \n",
    "    index = previous_selection\n",
    "    selection = row[index]\n",
    "    results += func(row_index+1, index, sum_+selection)\n",
    "    \n",
    "    index = previous_selection+1\n",
    "    if 0 <= index < length:\n",
    "        selection = row[index]\n",
    "        results += func(row_index+1, index, sum_+selection)\n",
    "    \n",
    "    return results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "12"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "paths = []\n",
    "for c_index, c in enumerate(A[0]):\n",
    "    paths.append(min(func(1, c_index, c)))\n",
    "min(paths)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "A = [\n",
    "    [1,2,3],\n",
    "    [4,5,6],\n",
    "    [7,8,9]\n",
    "]\n",
    "length = len(A)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "def func(row_index, previous_selection, sum_):\n",
    "    if (row_index >= length):\n",
    "        return [sum_]\n",
    "    \n",
    "    row = A[row_index]\n",
    "    selection1 = None\n",
    "    selection2 = None\n",
    "    selection3 = None\n",
    "    \n",
    "    index1 = previous_selection-1\n",
    "    if 0 <= index1 < length:\n",
    "        selection1 = row[index1]\n",
    "    \n",
    "    index2 = previous_selection\n",
    "    selection2 = row[index2]\n",
    "    \n",
    "    index3 = previous_selection+1\n",
    "    if 0 <= index3 < length:\n",
    "        selection3 = row[index3]\n",
    "        \n",
    "    if (selection1 and selection2 and selection3):\n",
    "        if selection1 > selection2 > selection3:\n",
    "            return func(row_index+1, index3, sum_+selection3)\n",
    "        if selection2 > selection3 > selection1:\n",
    "            return func(row_index+1, index1, sum_+selection1)\n",
    "        if selection3 > selection1 > selection2:\n",
    "            return func(row_index+1, index2, sum_+selection2)\n",
    "    if (selection1 and selection2):\n",
    "        if selection1 > selection2:\n",
    "            return func(row_index+1, index2, sum_+selection2)\n",
    "        else:\n",
    "            return func(row_index+1, index1, sum_+selection1)\n",
    "    if (selection2 and selection3):\n",
    "        if selection2 > selection3:\n",
    "            return func(row_index+1, index3, sum_+selection3)\n",
    "        else:\n",
    "            return func(row_index+1, index2, sum_+selection2)\n",
    "    if (selection1 and selection3):\n",
    "        if selection1 > selection3:\n",
    "            return func(row_index+1, index3, sum_+selection3)\n",
    "        else:\n",
    "            return func(row_index+1, index1, sum_+selection1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "12"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "paths = []\n",
    "for c_index, c in enumerate(A[0]):\n",
    "    paths.append(min(func(1, c_index, c)))\n",
    "min(paths)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "https://leetcode.com/problems/minimum-falling-path-sum\n",
    "\n",
    "\n",
    "Time Limit Exceeded\n",
    "\n",
    "\n",
    "```python\n",
    "class Solution:\n",
    "    def minFallingPathSum(self, A: List[List[int]]) -> int:\n",
    "        length = len(A)\n",
    "        \n",
    "        def func(row_index, previous_selection, sum_):\n",
    "            if (row_index >= length):\n",
    "                return [sum_]\n",
    "\n",
    "            row = A[row_index]\n",
    "            results = []\n",
    "\n",
    "            index = previous_selection-1\n",
    "            if 0 <= index < length:\n",
    "                selection = row[index]\n",
    "                results += func(row_index+1, index, sum_+selection)\n",
    "                \n",
    "            index = previous_selection\n",
    "            selection = row[index]\n",
    "            results += func(row_index+1, index, sum_+selection)\n",
    "\n",
    "            index = previous_selection+1\n",
    "            if 0 <= index < length:\n",
    "                selection = row[index]\n",
    "                results += func(row_index+1, index, sum_+selection)\n",
    "\n",
    "            return results\n",
    "\n",
    "        paths = []\n",
    "        for c_index, c in enumerate(A[0]):\n",
    "            paths.append(min(func(1, c_index, c)))\n",
    "        return min(paths)\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "https://leetcode.com/problems/minimum-path-sum/\n",
    "\n",
    "\n",
    "Time Limit Exceeded\n",
    "\n",
    "\n",
    "```python\n",
    "import math\n",
    "\n",
    "class Solution:\n",
    "    def minPathSum(self, grid: List[List[int]]) -> int:\n",
    "        #5:07\n",
    "        self.min_value = math.inf\n",
    "        limit_y = len(grid) - 1\n",
    "        limit_x = len(grid[0]) - 1 \n",
    "        \n",
    "        def travel(current_position, current_sum):\n",
    "            x = current_position[0]\n",
    "            y = current_position[1]\n",
    "            \n",
    "            if (x > limit_x or y > limit_y):\n",
    "                return \n",
    "            \n",
    "            current_sum += grid[y][x]\n",
    "            if (x == limit_x and y == limit_y):\n",
    "                if (current_sum < self.min_value):\n",
    "                    self.min_value = current_sum\n",
    "                    return\n",
    "            \n",
    "            travel((x+1, y), current_sum)\n",
    "            travel((x, y+1), current_sum)\n",
    "            \n",
    "        travel((0,0),0)\n",
    "        return self.min_value\n",
    "        #5:17\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
